import { useRef, useEffect, useState, useCallback, memo, useMemo } from 'react';
import type { FC } from 'react';
import { Tooltip, Typography } from '@mui/material';
import type { TypographyProps } from '@mui/material';
import { styled } from '@mui/material/styles';

// 改进的防抖函数，使用泛型以确保类型安全
const debounce = <T extends (...args: unknown[]) => void>(
  fn: T,
  delay: number = 100,
): ((...args: Parameters<T>) => void) => {
  let timer: ReturnType<typeof setTimeout> | null = null;
  return (...args: Parameters<T>): void => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
};

// 单行文本组件样式
const SingleLineTypography = styled(Typography)({
  overflow: 'hidden',
  textOverflow: 'ellipsis',
  whiteSpace: 'nowrap',
});

// 多行文本组件样式
const MultiLineTypography = styled(Typography)<{ maxLines: number }>(
  ({ maxLines }) => ({
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    display: '-webkit-box',
    WebkitLineClamp: maxLines,
    WebkitBoxOrient: 'vertical',
  }),
);

interface SingleLineTextWithTooltipProps extends TypographyProps {
  text: string;
}

const SingleLineTextWithTooltipBase: FC<SingleLineTextWithTooltipProps> = ({
  text,
  ...props
}) => {
  const textRef = useRef<HTMLParagraphElement | null>(null);
  const [isOverflowing, setIsOverflowing] = useState<boolean>(false);

  // 缓存检测函数
  const checkOverflow = useCallback((): void => {
    if (textRef.current) {
      setIsOverflowing(
        textRef.current.scrollWidth > textRef.current.clientWidth,
      );
    }
  }, []);

  useEffect(() => {
    // 初始检测
    checkOverflow();

    // 添加防抖的 resize 监听，使用类型安全的事件处理函数
    const handleResize = debounce(() => checkOverflow());
    window.addEventListener('resize', handleResize as EventListener);

    // 清理函数
    return () => {
      window.removeEventListener('resize', handleResize as EventListener);
    };
  }, [checkOverflow]);

  // 使用useMemo缓存tooltip标题
  const tooltipTitle = useMemo(
    () => (isOverflowing ? text : undefined),
    [isOverflowing, text],
  );

  return (
    <Tooltip
      title={tooltipTitle}
      arrow
      enterDelay={300}
      disableHoverListener={!isOverflowing}
    >
      <SingleLineTypography {...props} ref={textRef}>
        {text}
      </SingleLineTypography>
    </Tooltip>
  );
};

interface MultiLineTextWithTooltipProps extends TypographyProps {
  text: string;
  maxLines?: number; // 最大显示行数，默认3行
}

const MultiLineTextWithTooltipBase: FC<MultiLineTextWithTooltipProps> = ({
  text,
  maxLines = 3, // 默认3行
  ...props
}) => {
  const textRef = useRef<HTMLParagraphElement | null>(null);
  const [isOverflowing, setIsOverflowing] = useState<boolean>(false);

  // 检测文本是否溢出
  const checkOverflow = useCallback((): void => {
    if (textRef.current) {
      // 对比实际内容高度和可视区域高度
      setIsOverflowing(
        textRef.current.scrollHeight > textRef.current.clientHeight,
      );
    }
  }, []);

  useEffect(() => {
    // 初始检测
    checkOverflow();

    // 添加防抖的resize监听，使用类型安全的事件处理函数
    const handleResize = debounce(() => checkOverflow());
    window.addEventListener('resize', handleResize as EventListener);

    // 清理函数
    return () => {
      window.removeEventListener('resize', handleResize as EventListener);
    };
  }, [checkOverflow]);

  // 使用useMemo缓存tooltip标题
  const tooltipTitle = useMemo(
    () => (isOverflowing ? text : undefined),
    [isOverflowing, text],
  );

  return (
    <Tooltip
      title={tooltipTitle}
      arrow
      enterDelay={300}
      disableHoverListener={!isOverflowing}
    >
      <MultiLineTypography maxLines={maxLines} {...props} ref={textRef}>
        {text}
      </MultiLineTypography>
    </Tooltip>
  );
};

// 使用memo包装组件以避免不必要的重新渲染
export const SingleLineTextWithTooltip = memo(SingleLineTextWithTooltipBase);
export const MultiLineTextWithTooltip = memo(MultiLineTextWithTooltipBase);
